package cn.fotoit.product.chatServer;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.locks.ReentrantLock;


@Component
@ServerEndpoint(value = "/ws/chatServer/{userId}")
@Slf4j
public class ChatServer {


    static Map<String, Session> routeTab = new HashMap<>();  //用户名和websocket的session绑定的路由表

    // 连接建立成功调用的方法
    @OnOpen
    public void onOpen(@PathParam("userId") String userId, Session session) throws Exception {
        routeTab.put(userId, session);
        String message = getMessage("", "notice", routeTab.keySet());
        log.info("[" + userId + "]加入在线通信系统,、当前人数为" + routeTab.keySet().size() + "位");
        broadcast(message);

    }



//    @Scheduled(fixedRate = 10000)//10秒 执行一次  用于维持心跳
//    public void heatBroadcast() throws IOException {
//        String msg = " {\"msg\":\"\",\"type\":\"heart\",\"to\":\"\",\"from\":\"\"}";
//        broadcast(msg);
//    }

    // 连接关闭调用的方法
    @OnClose
    public void onClose(@PathParam("userId") String userId) throws IOException {
        routeTab.remove(userId);
        String message = getMessage("", "notice", routeTab.keySet());
        log.info("[" + userId + "]退出在线通信系统,、当前人数为" + routeTab.keySet().size() + "位");
        broadcast(message);
    }

    // 接收客户端的message,判断是否有接收人而选择进行广播还是指定发送
    @OnMessage
    public void onMessage(String _message) throws IOException {
        log.info(_message);
        JSONObject chat = JSON.parseObject(_message);
        String to = chat.getString("to");
        if (StringUtils.isEmpty(to)) {      //如果to为空,则广播;如果不为空,则对指定的用户发送消息
            broadcast(_message);
        } else {
            String[] userlist = to.split(",");
            for (String user : userlist) {
                if ((!StringUtils.isEmpty(user))&&routeTab.keySet().contains(user)) {
                    singleSend(_message, routeTab.get(user));     //分别发送给每个指定用户
                }
            }
        }
    }

    // 发生错误时调用
    @OnError
    public void onError(Throwable error) {
        error.printStackTrace();
    }

    // 广播消息
    public void broadcast(String message) throws IOException {
        for (String s : routeTab.keySet()) {
            Session session = routeTab.get(s);
            if (session != null&&session.isOpen()) {
                lock.lock();
                session.getBasicRemote().sendText(message);
                lock.unlock();
            }
        }
    }

    private  ReentrantLock lock = new ReentrantLock();
    //  对特定用户发送消息
    public void singleSend(String message, Session session) throws IOException {
        if (session != null&&session.isOpen()) {
            lock.lock();
            session.getBasicRemote().sendText(message);
            lock.unlock();
        }

    }


    //组装返回给前台的消息
    //type    信息类型 message消息  notice通知  order 命令   message
    //list    在线列表
    public String getMessage(String message, String type, Set<String> list) {
        JSONObject member = new JSONObject();
        member.put("msg", message);
        member.put("type", type);
        member.put("list", list);
        return member.toJSONString();
    }

}
